package com.eav.app.bluetoothsample

import android.util.Log
import java.io.BufferedReader
import java.io.File
import java.io.FileOutputStream
import java.io.InputStreamReader
import java.text.SimpleDateFormat

object LogCatHelper {
    private val TAG = "LogCatHelper"

    lateinit var dirPath: String//保存路径
    var logFileFormat: String = "yyyyMMdd" //log文件format string
    private val appid: Int//应用appid
    private var logThread: Thread? = null

    @Volatile
    private var logRunnable:LogRunnable? = null

    init {
        // 获取应用进程ID
        appid = android.os.Process.myPid()
    }

    /**
     * 启动log日志保存
     */
    fun start() {
        // 创建日志文件夹

        val dir = File(dirPath!!)
        if (!dir.exists()) {
            dir.mkdirs()
        }

        if (logThread == null) {
            logRunnable = LogRunnable(appid, dirPath!!, logFileFormat)
            logThread = Thread(logRunnable)
            logThread!!.start()
        }
    }


    private class LogRunnable(pid: Int, private val dirPath: String, private val logFileFormat: String) : Runnable {
        private val TAG = "LogCatHelper"
        private var mProcess: Process? = null
        private var fos: FileOutputStream? = null
        private var mReader: BufferedReader? = null
        private val cmds: String
        private val mPid: String
        @Volatile
        private var cancle:Boolean = false

        init {

            this.mPid = "" + pid
            cmds = "logcat *:e | grep \"($mPid)\""

            try {
                checkToCreateLogFile()
            } catch (e: Exception) {
                e.printStackTrace()
            }

        }

        @Throws(Exception::class)
        private fun checkToCreateLogFile() {
            val dir = File(dirPath)
            if (!dir.exists()) {
                dir.mkdirs()
            }

            val currentTime = System.currentTimeMillis()
            val dateFormat = SimpleDateFormat(logFileFormat)
            val file = File(dirPath, dateFormat.format(currentTime) + ".log")

            if (!file.exists()) {
                fos?.flush()
                IOUtil.close(fos)
                val success = file.createNewFile()
                Log.e(TAG,"create new file:${file.absolutePath} success:$success")
                fos = FileOutputStream(file, true)
            } else if (fos == null) {
                fos = FileOutputStream(file, true)
            }
        }

        fun cancel(){
            cancle = true
            Log.e(TAG,"cancel log")
        }

        override fun run() {
            while (!cancle) {
                try {
                    try {
                        checkToCreateLogFile()
                    } catch (e: Exception) {
                        e.printStackTrace()
                        Log.e(TAG, ExceptionUtil.getTrace(e))
                    }

                    Log.e(TAG, "start trance log process")
                    mProcess = Runtime.getRuntime().exec(cmds)
                    mReader = BufferedReader(InputStreamReader(mProcess!!.inputStream), 4096)
                    var line: String? = null
                    while ({
                            line = mReader!!.readLine();line
                        }() != null && !cancle) {
                        if (line!!.length == 0) {
                            continue
                        }
                        if (fos != null && line!!.contains(mPid)) {
                            fos!!.write((line + "\r\n").toByteArray())
                            fos!!.flush()
                        } else if (fos == null) {
                            Thread.sleep(200)
                            break
                        }
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                    Log.e(TAG, ExceptionUtil.getTrace(e))
                } finally {
                    Log.e(TAG, "stop trance log process")
                    try {
                        if (mProcess != null) {
                            mProcess!!.destroy()
                            mProcess = null
                        }
                    } catch (e: Exception) {
                        e.printStackTrace()
                        Log.e(TAG, ExceptionUtil.getTrace(e))
                    }

                    try {
                        IOUtil.close(mReader)
                        IOUtil.close(fos)
                        mReader = null
                        fos = null
                    } catch (e2: Exception) {
                        e2.printStackTrace()
                        Log.e(TAG, ExceptionUtil.getTrace(e2))
                    }

                }
            }

        }
    }

}